import _ from 'underscore';
import dispatcher from 'lib/dispatcher';
import { Scope } from 'lib/scopeFactory';
import ApiFactory from 'lib/ApiFactory';
import { dataSize } from 'lib/util/format';
import TimeStore from 'lib/stores/time-store';
import world from 'lib/geoJSON/world_geo.json';
import { numSecond2 } from 'lib/util/format';
import { coreApi, sortMap, parseToChart, parseToTopbar } from '../apis/core-util';

const supportedWorldMap = _(world.features).map((a) => a.properties['hc-key']);

let defaultItem = {
  name: '--',
  percent: '--',
  httpError: '--',
  networkError: '--',
};

export default class RootViewScope extends Scope {
  constructor(props, context) {
    super(props, context);

    this.$state = {
      right: -40,
      left: 110,
      loading: false,
      httpRequest: {
        // 平均响应时间趋势图
        chart0: {
          loading: true,
          value: '0.00ms',
          data: {
            series: []
          }
        },
        // 传输数据量趋势图
        chart1: {
          loading: true,
          value: '0.00B',
          data: {
            series: []
          }
        },
        // 吞吐量趋势图
        chart2: {
          loading: true,
          value: '0.00cpm',
          data: {
            series: []
          }
        }
      },
      // 错误
      error: {
        loading: true,
        network: '--',
        http: '--',
        data: {
          series: []
        }
      },
      // 运营商
      carries: {
        loading: true,
        top2: [defaultItem, defaultItem]
      },
      // 操作系统
      os: {
        loading: true,
        top2: [defaultItem, defaultItem]
      },
      // HTTP响应时间地域分布
      geo: {
        loading: true
      }
    };
  }

  $settime(payload){
    this.$state.error.loading = true;
    this.$state.carries.loading = true;
    this.$state.os.loading = true;
    this.$state.geo.loading = true;

    _.forEach(this.$state.httpRequest, (chart) => {
      chart.loading = true;
    });
    this.emit();

    this.fetch();
  }

  fetch() {
    let keyTransactionId = this.viewInstance.props.params.id;

    let getErrorRate = (condition) => {
      let conditions = Object.assign({}, {
        limit: 1,
        urlName: 'errorrate',
        classify: 'app',
        viewKey: 'error_rate',
        order: sortMap['error_rate']
      }, condition);

      return coreApi(conditions, TimeStore.getValue).fetch().then((data, params) => {
        // 求出百分比
        let result = {
          data: data,
          result: parseToChart(data, params),
          percent: '0.00%'
        };

        if (_.has(data.result[0], 'combData')) {
          result.percent = (data.result[0].combData.val / data.result[0].combData.count * 100).toFixed(2) + '%';
        }

        return result;
      });
    };

    // ===================================
    // ========== 获取HTTP错误率 ==========
    // ===================================
    getErrorRate({
      keyTransactionId,
      statusCode: 400
    }).then((http) => {
      // 获取网络错误率
      getErrorRate({
        keyTransactionId,
        errorCode: 0
      }).then((network) => {
        if (network.result.series[0]) {
          network.result.series[0].name = 'networkError';
          network.result.series[0].type = 'column';
        }

        if (http.result.series[0]) {
          http.result.series[0].name = 'httpError';
        }

        this.$state.error.data.series = http.result.series.concat(network.result.series);
        this.$state.error.http = http.percent; // HTTP错误百分比
        this.$state.error.network = network.percent; // 网络错误百分比
      }).always(() => {
        this.$state.error.loading = false;
        this.emit();
      });
    });


    let padItem = (target) => {
      if (target.top2.length === 0) {
        target.top2 = [defaultItem, defaultItem];
      } else if (target.top2.length === 1) {
        target.top2.push(defaultItem);
      }
      return target;
    };

    // ===========================
    // ========== 运营商 ==========
    // ===========================
    coreApi({
      limit: 5,
      size: 1,
      urlName: 'httptransaction',
      classify: 'networkgeneration',
      classifyKeyField: 'time', // 平均响应时间
      classifyCountField: 'num',
      viewKey: 'resp_count',
      order: 3,
      keyTransactionId: this.viewInstance.props.params.id
    }, TimeStore.getValue).fetch().then((data, params) => {
      // 饼图数据
      this.$state.carries.data = parseToChart(_.extend({}, data, {
          result:_(data.result).chain().filter((r) => {
            return r.combData.val !== 0
          }).map(function(r){
            return _.extend({},r,{
              data:[r.combData]
            })
          }).value()
        }), params);

      let ids = [];
      // 运营商 - 平均响应时间 - top 2 详细信息
      this.$state.carries.top2 = data.result.slice(0, 2).map((item, index) => {
        ids.push(item.id);
        // 平均响应时间
        return {
          name: item.name,
          percent: numSecond2((item.combData.val / item.combData.count)).replace(/\s+/g, ''),
          httpError: '',
          networkError: ''
        };
      });

      this.$state.carries = padItem(this.$state.carries);

      // 获取top2的各错误率 http error.
      ids.forEach((id, index) => {
        getErrorRate({
          networkOperatorId: id,
          keyTransactionId,
          classify: 'networkgeneration',
          statusCode: 400
        }).then((res) => {
          this.$state.carries.top2[index].httpError = res.percent;
        }).always(() => {
          this.$state.carries.loading = false;
          this.emit();
        });

        // network error.
        getErrorRate({
          networkOperatorId: id,
          keyTransactionId,
          classify: 'networkgeneration',
          errorCode: 0
        }).then((res) => {
          this.$state.carries.top2[index].networkError = res.percent;
        }).always(() => {
          this.$state.carries.loading = false;
          this.emit();
        });
      });
    }).always(() => {
      this.$state.carries.loading = false;
      this.emit();
    });

    // =============================
    // ========== 操作系统 ==========
    // =============================
    coreApi({
      limit: 5,
      size: 1,
      urlName: 'httptransaction',
      classify: 'osversion',
      osId: BlueWare.osId,
      classifyKeyField: 'time',
      classifyCountField: 'num',
      viewKey: 'resp_count',
      order: 3,
      keyTransactionId: this.viewInstance.props.params.id
    }, TimeStore.getValue).fetch().then((data, params) => {
      // 饼图数据
      this.$state.os.data = parseToChart(_.extend({}, data, {
          result:_(data.result).chain().filter((r) => {
            return r.combData.val !== 0
          }).map(function(r){
            return _.extend({},r,{
              data:[r.combData]
            })
          }).value()
        }), params);

      let ids = [];

      // 运营商 - 平均响应时间 - top 2 详细信息
      this.$state.os.top2 = data.result.slice(0, 2).map((item, index) => {
        ids.push(item.id);

        // 平均响应时间
        return {
          name: item.name,
          percent: numSecond2((item.combData.val / item.combData.count)).replace(/\s+/g, ''),
          httpError: '',
          networkError: ''
        };
      });

      this.$state.os = padItem(this.$state.os);

      // 获取top2的各错误率
      ids.forEach((id, index) => {
        getErrorRate({
          osVersionId: id,
          osId: BlueWare.osId,
          keyTransactionId,
          classify: 'osversion',
          statusCode: 400,
        }).then((res) => {
          this.$state.os.top2[index].httpError = res.percent;
        }).always(() => {
          this.$state.os.loading = false;
          this.emit();
        });

        getErrorRate({
          osVersionId: id,
          osId: BlueWare.osId,
          keyTransactionId,
          classify: 'osversion',
          errorCode: 0
        }).then((res) => {
          this.$state.os.top2[index].networkError = res.percent;
        }).always(() => {
          this.$state.os.loading = false;
          this.emit();
        });
      });
    }).always(() => {
      this.$state.os.loading = false;
      this.emit();
    });

    // 二次封装，方便右侧的图表使用，逻辑基本一致
    let fetHttpTransaction = (chartKey, keyField, viewKey) => {
      return coreApi({
        limit: 1,
        urlName: 'httptransaction',
        classify: 'app',
        classifyKeyField: keyField,
        classifyCountField: 'num',
        viewKey,
        order: sortMap[viewKey],
        keyTransactionId: this.viewInstance.props.params.id
      }, TimeStore.getValue).fetch().then((data, params) => {
        // 数据处理好之后直接返回，避免过多的操作
        return {
          result: parseToChart(data, params),
          data: data.result
        };
      }).always(() => {
        this.$state.httpRequest[chartKey].loading = false;
        this.emit();
      });
    };

    // 平均响应时间趋势图
    fetHttpTransaction('chart0', 'time', 'avg_resp').then(({value, result, data}) => {
      // 数据存储，不能直接覆盖该对象
      if (_.has(data[0], 'combData')) {
        this.$state.httpRequest.chart0.value = numSecond2((data[0].combData.val / data[0].combData.count)).replace(/\s+/g, '');
        this.$state.httpRequest.chart0.data = result;
      }
    });

    // 传输数据量趋势图
    fetHttpTransaction('chart1', 'receive', 'total_receive_size').then(({value, data, result}) => {
      // 数据存储，不能直接覆盖该对象
      if (_.has(data[0], 'combData')) {
        this.$state.httpRequest.chart1.value = dataSize(data[0].combData.val).replace(/\s+/g, '');
        this.$state.httpRequest.chart1.data = result;
      }
    });

    // 吞吐量趋势图
    fetHttpTransaction('chart2', 'num', 'thp').then(({value, data, result}) => {
      if (_.has(data[0], 'combData')) {
        // 数据存储，不能直接覆盖该对象
        // 计算公式：result = count / ((endTime - startTime) / 60000)
        let {st, et, count} = data[0].combData,
            minutes = (et - st) / 60000; // 算出一共有多少分钟

        this.$state.httpRequest.chart2.value = `${(count / minutes).toFixed(2)}cpm`;
        this.$state.httpRequest.chart2.data = result;
      }
    });

    // ========================================
    // ========== HTTP响应时间地域分布 ==========
    // ========================================
    coreApi({
      urlName: 'httptransaction',
      classify: 'countrycode',
      limit: null,
      size: 1,
      viewKey: 'avg_resp',
      classifyKeyField: 'time',
      classifyCountField: 'num',
      order: sortMap['avg_resp'],
      keyTransactionId
    },TimeStore.getValue).fetch().then((data, params) => {
      this.$state.geo = {
        mapData: world,
        joinBy: 'hc-key',
        data: _.chain(parseToTopbar(data, params))
          .map((a) => _.extend({}, a, {name: a.name.toLowerCase()}))
          .filter((a) => _.contains(supportedWorldMap, a.name))
          .map((p) => {
            return {
              value: p.value,
              fmtVal: p.fmtVal,
              name: p.name,
              label: p.label,
              startTime: p.startTime,
              endTime: p.endTime,
              'hc-key': p.name
            }
          }).value()
      }
    }).always(() => {
      this.$state.geo.loading = false;
      this.emit();
    });
  }

  $load() {
    this.fetch();
  }
}
